<html>
<head>
    <script src="../../resources/js-test.js"></script>
    <script src="../../resources/visibility.js"></script>
    <script>
        description('<a href="https://bugs.webkit.org/show_bug.cgi?id=98474">Bug 98474</a>: Throttle DOM timers on hidden pages.');

        var jsTestIsAsync = true;
        var previousTime = 0;
        var timerCount = 0;
        var firstTimerWhileNotVisible = true;
        var isPageVisible = true;
        var timeoutInterval = 100;
        // Some of our testing hardware runs very slowly, so we need a generous
        // tolerance value.
        var tolerance = 200;
        var timerAlignmentInterval = 1000;

        function testTimer()
        {
            var time = Date.now();
            if (!isPageVisible) {
                if (firstTimerWhileNotVisible) {
                    firstTimerIntervalWhilePageNotVisible = time - previousTime;
                    // Even if (tolerance > timeoutInterval), we should never
                    // get a negative elapsed time, so clamp minValue to zero.
                    var minValue = Math.max(0, timeoutInterval - tolerance);
                    shouldBeGreaterThanOrEqual("firstTimerIntervalWhilePageNotVisible", minValue.toString());
                    var maxValue = timeoutInterval + timerAlignmentInterval + tolerance;
                    shouldBeTrue("firstTimerIntervalWhilePageNotVisible <= " + maxValue);
                    firstTimerWhileNotVisible = false;
                } else {
                    timerIntervalWhilePageNotVisible = time - previousTime;
                    shouldBeCloseTo("timerIntervalWhilePageNotVisible", timerAlignmentInterval, tolerance);
                }
            } else {
                timerIntervalWhilePageVisible = time - previousTime;
                shouldBeCloseTo("timerIntervalWhilePageVisible", timeoutInterval, tolerance);
            }

            timerCount++;
            previousTime = time;

            var promise;
            if (timerCount == 1) {
                promise = setMainWindowHidden(true);
                isPageVisible = false;
            } else if (timerCount == 3) {
                promise = setMainWindowHidden(false);
                isPageVisible = true;
            } else if (timerCount < 5) {
                promise = Promise.resolve();
            } else {
                finishJSTest();
                return;
            }
            promise.then(() => {
                previousTime = Date.now();
                setTimeout(testTimer, timeoutInterval);
            });
        }

        function runTest()
        {
            if (!window.testRunner) {
                debug('This test requires testRunner');
                return;
            }

            var timeoutIntervalSpans = document.getElementsByClassName('timeoutInterval');
            for (var i = 0; i < timeoutIntervalSpans.length; i++)
                timeoutIntervalSpans[i].innerText = timeoutInterval;

            document.getElementById('alignmentInterval').innerText = timerAlignmentInterval / 1000;

            testRunner.dumpAsText();
            previousTime = Date.now();
            setTimeout(testTimer, timeoutInterval);
        }
    </script>
</head>
<body onload="runTest()">
    <p>
    This test measures the time taken to fire a <span class="timeoutInterval"></span>ms DOM Timer when the page visibility is set to "visible", "hidden", and then back to "visible".  Due to page timer throttling, the timer should fire close to <span id="alignmentInterval"></span>s when page is hidden.  And it should fire close to <span class="timeoutInterval"></span>ms, when the page is visible.
    </p>
</body>
</html>
